#ifndef MODELFORMATION_H
#define MODELFORMATION_H

#include <QVector3D>
#include <QVector>
#include <limits>
#include <QSet>


bool floatEquals(float a, float b, float epsilon = std::numeric_limits<float>::epsilon());
bool IsEqual(float f1, float f2, int absDelta);

constexpr float vertexEpsilon = 1e-5f;
constexpr int absDelta = 1e-5f / 1.19e-7f;

struct Vertex
{
    QVector3D pos;
    QVector3D norm;
    QVector4D color;

    bool operator==(const Vertex &other) const {
        return IsEqual(pos.x(), other.pos.x(), absDelta) &&
               IsEqual(pos.y(), other.pos.y(), absDelta) &&
               IsEqual(pos.z(), other.pos.z(), absDelta);
    }

    //bool operator==(const Vertex &other) const {
    //    return pos == other.pos;
    //}

    bool operator!=(const Vertex &other) const {
        return !(*this == other); // 使用 == 运算符的反义
    }

    bool operator<(const Vertex &other) const {
        // 按 pos 的 x, y, z 依次比较
        if (!IsEqual(pos.x(), other.pos.x(), absDelta)) return pos.x() < other.pos.x();
        if (!IsEqual(pos.y(), other.pos.y(), absDelta)) return pos.y() < other.pos.y();
        return pos.z() < other.pos.z();
    }

    // 计算 Vertex 的哈希值
    uint hash() const {
        uint hashValue = qHash(static_cast<int>(pos.x() * 100000)); // 将坐标放大后取整
        hashValue ^= qHash(static_cast<int>(pos.y() * 100000)) + 0x9e3779b9 + (hashValue << 6) + (hashValue >> 2);
        hashValue ^= qHash(static_cast<int>(pos.z() * 100000)) + 0x9e3779b9 + (hashValue << 6) + (hashValue >> 2);
        return hashValue;
    }
};

// 为 Vertex 提供哈希函数，以便在 QSet 中使用
inline uint qHash(const Vertex &vertex, uint seed = 0) {
    return vertex.hash() ^ seed;
}

struct Edge
{
    Vertex v1, v2;
    QVector3D norm;

    // 重载 == 运算符，用于比较两个边是否相等
    bool operator==(const Edge &other) const {
        return (v1 == other.v1 && v2 == other.v2) || (v1 == other.v2 && v2 == other.v1);
    }

    bool operator<(const Edge &other) const {
        // 使用 Vertex 的 < 运算符
        if (v1 != other.v1) return v1 < other.v1;
        return v2 < other.v2;
    }

    // 自定义哈希函数
    uint hash() const {
        uint hash1 = v1.hash();
        uint hash2 = v2.hash();
        return qMin(hash1, hash2) ^ qMax(hash1, hash2); // 确保边的哈希值与顶点顺序无关
    }
};

// 为 Edge 提供哈希函数，以便在 QSet 中使用
inline uint qHash(const Edge &edge, uint seed = 0) {
    return edge.hash() ^ seed;
}

// 边表示的三角面片
struct Triangle
{
    Edge e1, e2, e3;
};

// 点表示的三角面片
struct Mesh
{
    QVector3D v1, v2, v3;
    QVector3D normal;
    quint16 info;
    bool operator==(const Mesh &other) const {
        return v1 == other.v1 && v2 == other.v2 && v3 == other.v3;
    }
};

struct Layer
{
    QVector<Vertex> points;
};

#endif // MODELFORMATION_H
